<?php
defined( '_JEXEC' ) or die( 'Restricted Access' );
/**
 * @version     $Id$
 * @package     Virtuemart
 * @subpackage  GoodRelations Module
 * @copyright   Copyright (C) 2010 Alex Stolz - All rights reserved.
 * @license     LGPL
 */

// include ARC2 framework
require_once(dirname(__FILE__).DS.'arc'.DS.'ARC2.php');
require_once(dirname(__FILE__).DS.'rdfa'.DS.'h2o'.DS.'h2o.php');
require_once(dirname(__FILE__).DS.'helper.php');
$cache = "file";

define("BASE_URI", JURI::base());
define("RDFA_DIR", dirname(__FILE__).DS.'rdfa'.DS);
$sess = new ps_session;
define("SHOP_URI", preg_replace("/&amp;/i", "&", BASE_URI.preg_replace("/^\//i", "", str_replace(JURI::base(true), "", $sess->url("?option=com_virtuemart")))) );
define("IMAGEBASEPATH", BASE_URI.preg_replace("/^\//i", "", str_replace(JPATH_BASE, "", IMAGEPATH)));

/**
 * GoodRelations Extension Controller
 *
 * core class of the application, where RDFa-pages are created
 *
 * @package    Virtuemart
 * @subpackage GoodRelations Module
 * @link       http://code.google.com/p/goodrelations-for-joomla/
 * @since      Class available since Release 0.1
 */
class ModSemanticWebController {

	var $contentType;
	var $encoding;
	var $sitemap_uri;
	var $_timeout;
	var $_params;
	var $db, $db2, $psp, $sess, $lang;
	var $object_properties;
	var $features;
	var $categories;
	var $product_data;
	var $datasheet_data;
	var $manufacturer_data;
	var $company_data;
	var $store_data;
	var $review_data;
	
	function __construct() {
		$this->db = new ps_DB;
		$this->sess = new ps_session;
		$this->contentType = "application/xml";
		$this->encoding = "utf-8";
		$this->sitemap_uri = "sitemap.xml";
		$lang = &JFactory::getLanguage();
		$this->lang = $lang->getTag();
		$this->object_properties = array("Weight", "Length", "Width", "Height");
	}
	
	function _init_psproduct() {
		$this->psp = new ps_product;
	}

	// check, if the virtuemart component is enabled
	function isVirtueMartEnabled() {
		$db =& JFactory::getDBO();
		$enabled = NULL;
		
		$db->setQuery("select enabled from #__components where ".$db->nameQuote( 'option' )."=".$db->quote( 'com_virtuemart' )." and parent='0'");
		if($row = $db->loadAssoc()) {
			$enabled = $row['enabled'];
		}
		
		if($enabled === NULL)
			return false;
		else
			return $enabled?true:false;
	}
	
	// load the params from the backend
	function setParams($params) {
		$this->_params = $params;
	}
	
	// set the timeout in seconds before a cached version is refreshed
	function setTimeout($timeout) {
		$this->_timeout = $timeout;
	}
	
	// strip any occurrence of possible tags
	function strip_tags($string) {
		return trim(preg_replace("/(<[^>]*>|\{[^\}]*\}|\[[^\]]*\])/", "", $string));
	}
	
	function createSitemap() {
		$company_info = &$this->company_data;
		$company_info = $this->getCompanyInfo();
		$base_uris = array();
		$base_uris[] = array(
			'uri' => BASE_URI,
			'lastmod' => date("Y-m-d"),
			'changefreq' => "daily",
			'priority' => "1.0");
		if(SHOP_URI != BASE_URI)
		    $base_uris[] = array(
				'uri' => SHOP_URI,
				'lastmod' => date("Y-m-d"),
				'changefreq' => "daily",
				'priority' => "0.8");
		$sitemap_data = array(
			'uris' => array_merge(
				$base_uris,
				$this->getAllProductURIs()
			)
		);
		include(RDFA_DIR.'sitemap.php');
		
		// check existence and validity of the file
		if (file_exists($this->sitemap_uri) && (time()-filemtime($this->sitemap_uri) < $this->_timeout)) {
			return;
		}
		$sitemap_file = fopen($this->sitemap_uri, "w+");
		if ($sitemap_file) {
			// write contents into sitemap file
			fputs($sitemap_file, $sitemap_contents); // got sitemap_contents through include from above
			fclose($sitemap_file);
			// $this->notifySWSE(); // disabled, now handled via mod_goodrelations.php
			return true;
		} else {
			echo "<br /><b>Error creating Sitemap file, please check write permissions.</b><br />";
		}
	}
	
	// create w3c date format from any different time/date format
	function w3cDate($time, $days_offset=0) {
		$time = $time+$days_offset*86400;
		if ((int) PHP_VERSION >= 5)
			return date('c', $time);
		else {
			$offset = date('O', $time);
			return date('Y-m-d\TH:i:s', $time).substr($offset, 0, 3).':'.substr($offset, -2);
		}
	}
	
	// notify semantic web search engines
	function notifySWSE($submission_url="http://gr-notify.appspot.com/submit?uri=") {
		global $vmLogger;
		$db = &$this->db;
		$email = $this->company_data["email"];
		// submit a sitemap if exists
		if(file_exists($this->sitemap_uri)) {
		    $ping_url = $submission_url.urlencode(BASE_URI.$this->sitemap_uri).($email==""?"":"&contact=".urlencode($email))."&agent=goodrelations-for-joomla-".$this->_params->get('version');
		}
		else {
		    $ping_url = $submission_url.urlencode(BASE_URI).($email==""?"":"&contact=".urlencode($email))."&agent=goodrelations-for-joomla-".$this->_params->get('version');
		}
		
	    if(strpos(BASE_URI, "://localhost") === false) // avoid submitting "://localhost" patterns
		{
			$ping_ok = $this->_httpGet($ping_url);
		}
	    
	    if($ping_ok) {
			$db->query("select params from #__modules where module='mod_goodrelations'" );
			if($db->next_record()) {
				$param_array = explode("\n", $db->f('params'));
				$new_param_array = array();
				$last_submit_exists = false;
				foreach($param_array as $equation) {
					$param = trim($equation);
					list($param_name, $param_value) = explode("=", $param);
					if(strpos($param_name, "ping_submission_base_uri") !== false) {
						$param = "ping_submission_base_uri=".$param_value.BASE_URI;
					}
					if(!empty($param))
						$new_param_array[] = $param;
				}
				$params = implode("\n", $new_param_array);
				$db->query("update #__modules set params='$params' where module='mod_goodrelations'");
			}
		}
	}
	
	// perform HTTP GET on endpoint with given URL
	function _httpGet($url) {
		// file operations are allowed
		if (ini_get('allow_url_fopen') == '1') {
			$str = file_get_contents($url);
			if($str === false) {
				$http_status_code = "";
			    for($i=0; $i<count($http_response_header); $i++)
			    {
			        if(strncasecmp("HTTP", $http_response_header[$i], 4)==0)
			        {
						// determine HTTP response code
						$http_status_code = preg_replace("/^.{0,9}([0-9]{3})/i", "$1", $http_response_header[$i]);
			            break;
			        }
			    }
				echo "<p class=\"error\">Submission failed: ".$http_status_code."</p>";
			}
			return $str;
		}
		// file operations are disallowed, try it like curl
		else {
			$url = parse_url($url);
			$port = isset($url['port'])?$url['port']:80;

			$fp = fsockopen($url['host'], $port);

			if(!$fp) {
				echo "<p class=\"error\">Cannot retrieve $url</p>";
				return false;
			}
			else {
				// send the necessary headers to get the file
				fwrite($fp, "GET ".$url['path']."?".$url['query']." HTTP/1.0\r\n".
					"Host:". $url['host']."\r\n".
					"Accept: text/html\r\n".
					"User-Agent: GoodRelations Extension for Joomla v2\r\n".
					"Connection: close\r\n\r\n");

				// retrieve response from server
				$buffer = "";
				$status_code_found = false;
				$is_error = false;
				while($line = fread($fp, 4096))
				{
					$buffer .= $line;
					if(!$status_code_found && ($pos=strpos($line, "HTTP"))>=0) {
						// extract HTTP response code
						$response = explode("\n", substr($line, $pos));
						$http_status_code = preg_replace("/^.{0,9}([0-9]{3})/i", "$1", $response[0]);
						$is_error = !preg_match("/(200|406)/i", $http_status_code); // accepted status codes not resulting in error are 200 and 406
						$status_code_found = true;
					}
				}
				fclose($fp);
				
				if($is_error) {
					echo "<p class=\"error\">Submission failed: ".$http_status_code."</p>";
					return false;
				}
				$pos = strpos($buffer,"\r\n\r\n");
				return substr($buffer,$pos);
			}
		}
	}
	
	// create the goodrelations rich snippet
	function getRDFaSnippet($type='all') {
		$pid = intval($_REQUEST['product_id']);
		$object_properties = &$this->object_properties;
		
		switch($type) {
			case "categories":
				$categories = &$this->categories;
				$categories = $this->getAllCategories();
				$company_data = &$this->company_data;
				$company_data = $this->getCompanyInfo();
				include(RDFA_DIR.'categories.php');
				break;
			case "product":
				$product_data = &$this->product_data;
				$product_data = $this->getProductDetailsByProductId($pid);
				include(RDFA_DIR.'product.php');
				break;
			case "manufacturers":
				$manufacturer_data = &$this->manufacturer_data;
				$manufacturer_data = $this->getAllManufacturerData();
				include(RDFA_DIR.'manufacturers.php');
				break;
			case "company":
				$company_data = &$this->company_data;
				$company_data = $this->getCompanyInfo();
				include(RDFA_DIR.'company.php');
				break;
			case "vendor":
				$store_data = &$this->store_data;
				$store_data = $this->getAllStoreData();
				include(RDFA_DIR.'store.php');
				break;
			case "review":
				$review_data = &$this->review_data;
				$review_data = $this->getReview($pid);
				include(RDFA_DIR.'review.php');
				break;
			case "all":
			default:
				$categories = &$this->categories;
				$categories = $this->getAllCategories();
				$product_data = &$this->product_data;
				$product_data = $this->getProductDetailsByProductId($pid);
				$manufacturer_data = &$this->manufacturer_data;
				$manufacturer_data = $this->getAllManufacturerData();
				$company_data = &$this->company_data;
				$company_data = $this->getCompanyInfo();
				$store_data = &$this->store_data;
				$store_data = $this->getAllStoreData();
				$review_data = &$this->review_data;
				$review_data = $this->getReview($pid);
				
				$cache = $this->_params->get("cache");
				$cache_dir = $this->_params->get("cache_dir");
				
				if($cache == "1")
				    $cache = "file";
				else
				    $cache = false;
				
				include(RDFA_DIR.'categories.php');
				include(RDFA_DIR.'product.php');
				include(RDFA_DIR.'manufacturer.php');
				include(RDFA_DIR.'company.php');
				include(RDFA_DIR.'store.php');
				include(RDFA_DIR.'review.php');
		}
	}
	
	// fetch all parameter names that are instances of an element (like eligibleRegions) in goodrelations
	function getAllParametersFromElement($search) {
		$db = &$this->db;
		$db->query("select params from #__modules where module='mod_goodrelations'");
		if($db->next_record()) {
			$param_array = explode("\n", $db->f('params'));
			foreach($param_array as $equation) {
				list($param_name, $param_value) = explode("=", trim($equation));
				if(strpos($param_name, $search) !== false && $param_name != '') { // key cannot be empty
					$param_key = ereg_replace('(_|'.$search.')', '', $param_name);
					if($param_value == '0') // skip radio buttons set to zero ('No')
						continue;
					else if($param_value == '1') { // one of the radio buttons ('Yes')
						if(($param_value = $this->_params->get($param_key."_duration")) != NULL)
							$param[$param_key] = $param_value; // assign duration of warranty in months
						else
							$param[$param_key] = true; // assign true
					}
					else { // a text field param
						$param[$param_key] = $param_value;
					}
				}
			}
			return $param;
		}
	}
	
	function getProductDetailsByProductId($product_id) {
		$db = &$this->db;
		if(!$this->psp)
			$this->_init_psproduct();
		$psp = &$this->psp;
		$sess = &$this->sess;
		$product = array();

		$db->query("select product_name, product_id, product_parent_id, vendor_id, product_sku, product_s_desc, product_desc, product_thumb_image, product_full_image,"
		        . " product_special, product_discount_id, product_weight, product_weight_uom, product_length, product_width, product_height, product_lwh_uom, product_url,"
		        . " product_in_stock, product_available_date"
		        . " from #__{vm}_product"
		        . " where product_id='$product_id' and product_publish='Y'");
		
		$product_special = "";
		$product_discount_id = 0;
		if($db->next_record()) {
		    $db_manufacturer = new ps_DB;
		    $db_parent = new ps_DB;
		    $db_category = new ps_DB;
    		$db_manufacturer->query("select manufacturer_id from #__{vm}_product_mf_xref where product_id='$product_id'");
		    
			$parent_id = $db->f('product_parent_id');
			if($parent_id > 0) {
				$db_parent->query("select product_name, product_s_desc, product_desc,"
						. " product_thumb_image, product_full_image"
						. " from #__{vm}_product"
						. " where product_id='$parent_id'");
				$db_category->query("select category_id from #__{vm}_product_category_xref where product_id='$parent_id'");
		    }
			else {
			    $db_category->query("select category_id from #__{vm}_product_category_xref where product_id='$product_id'");
			}
			$product['maker'] = "urn:goodrelations_shop_extensions:goodrelations-for-joomla:v".$this->_params->get('version');
			$product['product_name'] = $this->strip_tags($db->f('product_name')?$db->f('product_name'):$db_parent->f('product_name'));
			$product['category_uri'] = "self:category_".$db_category->f('category_id');
			$product['product_short'] = $this->strip_tags($db->f('product_s_desc')?$db->f('product_s_desc'):$db_parent->f('product_s_desc'));
			$product['product_long'] = $this->strip_tags($db->f('product_desc')?$db->f('product_desc'):$db_parent->f('product_desc'));
			$product['language'] = $this->lang;
			$product['company_uri'] = SHOP_URI."#company_data";
			$product['stock_level'] = number_format(max($db->f('product_in_stock'), 0), 2, ".", "");
			$u = &JURI::getInstance(BASE_URI);
			$p_uri_path = preg_replace("/&amp;/i", "&", $sess->url('index.php?page=shop.product_details&product_id='.$product_id));
			$product['product_type'] = "gr:SomeItems";
			if($this->_params->get('offer_individuals')) {
				$product['product_type'] = "gr:Individual";
				$product['stock_level'] = 0; // invalidate stock level, if individual products are sold
			}
			$product['product_uri'] = $u->getScheme().":".DS.DS.$u->getHost().($u->getPort()?":".$u->getPort():"").DS.preg_replace("/^\//i", "", $p_uri_path);
			$product['valid_from'] = $this->w3cdate(time());//$db->f('product_available_date'));
			$product['valid_through'] = $this->w3cdate(time(), $this->_params->get('offering_validity') /* fetch offering validity from backend */);
			$f_image = ($db->f('product_full_image')?$db->f('product_full_image'):$db_parent->f('product_full_image'));
			$t_image = ($db->f('product_thumb_image')?$db->f('product_thumb_image'):$db_parent->f('product_thumb_image'));
			$product['product_image_uri'] = $f_image?IMAGEBASEPATH."product/".$f_image:"";
			$product['product_thumbnail_uri'] = $t_image?IMAGEBASEPATH."product/".$t_image:"";
			$product['sku'] = $db->f('product_sku');
			$product['stock_unit'] = "C62";
			$product['manufacturer_uri'] = SHOP_URI."#manufacturer_".$db_manufacturer->f('manufacturer_id');
			$product_special = $db->f('product_special');
			$product_discount_id = $db->f('product_discount_id');
			
			$product['weight'] = number_format(max($db->f('product_weight'), 0), 2, ".", "");
			$product['width'] = number_format(max($db->f('product_width'), 0), 2, ".", "");
			$product['length'] = number_format(max($db->f('product_length'), 0), 2, ".", "");
			$product['height'] = number_format(max($db->f('product_height'), 0), 2, ".", "");
			
			$prefix_self = array();
			$prefix_self['ns_prefix'] = 'self';
			$prefix_self['ns_uri'] = SHOP_URI."#";
			$product['prefixes'] = array($prefix_self);
			
			// unit of measurement
			if(sizeof($tmp_weight = $this->getAllParametersFromElement('uom_weight'))>0)
				$product['uom']['weight'] = array_pop($tmp_weight);
			if(sizeof($tmp_lwh = $this->getAllParametersFromElement('uom_lwh'))>0)
				$product['uom']['lwh'] = array_pop($tmp_lwh);
			
			$features = array();
			foreach ($this->object_properties as $item) {
				$name = strtolower($item);
				$oprop = array();
				$oprop['type'] = "quantitative";
				$oprop['datatype'] = "float";
				if($name=="length")
					$oprop['uri'] = "gr:depth";
				else
					$oprop['uri'] = "gr:".$name;
				$oprop['unit_code'] = $item=="Weight"?$product['uom']["weight"]:$product['uom']["lwh"];
				$oprop['value'] = number_format($product[$name], 2, ".", "");
				$oprop['name'] = $name;
				if($oprop['value']>0)
					$features[] = $oprop;
			}
			$product['features'] = $this->features = $features;
		}

		// session specific variable auth (useful for show_price_including_tax, etc.)
		$auth = $_SESSION['auth'];
		// is tax included?
		$tax_included = $auth["show_price_including_tax"];
		$product['vat'] = $tax_included?"true":"false";

		// product tax
		$product_tax = $tax_included?$psp->get_product_taxrate($product_id):0.00;
		// product price
		$product_price_raw = $psp->get_price($product_id);
		$product_base_price = $GLOBALS['CURRENCY']->convert($product_price_raw['product_base_price'], $product_price_raw['product_currency'], $GLOBALS['product_currency']);
		$product_base_price = $product_base_price*(1+$product_tax);
		$product_currency = $GLOBALS['product_currency'];
		$product['price'] = number_format(max($product_base_price, 0), 2, ".", "");
		$product['currency'] = $product_currency;

		// price quantity
		$db_price_quantity = new ps_DB;
		$db_price_quantity->query("select price_quantity_start, price_quantity_end from #__{vm}_product_price where product_id='$product_id' and shopper_group_id='".$auth["shopper_group_id"]."'");
		if($db_price_quantity->next_record()) {
			$product['price_quantity_start'] = max($db_price_quantity->f('price_quantity_start'), 0);
			$product['price_quantity_end'] = max($db_price_quantity->f('price_quantity_end'), 0);
		}

		// HAS YET TO BE IMPLEMENTED
		$elements = array(
			'BusinessEntityType',
			'DeliveryMethod',
			'PaymentMethod',
			'WarrantyScope'
		);
		
		foreach($elements as $search) {
			$parameter_array_name = strtolower(ereg_replace('^_', '', ereg_replace('[A-Z]','_\\0',$search)));
			$$parameter_array_name = $this->getAllParametersFromElement($search); // get parameters from backend
		}

		// offering details got from master data in the backend
		$rdfa_string = "";
		$namespaces = array();
		$namespaces['gr'] = "http://purl.org/goodrelations/v1#";
		foreach($elements as $element) {

			$property = NULL;
			$parameter_array_name = strtolower(ereg_replace('^_', '', ereg_replace('[A-Z]','_\\0',$element)));

			switch($element) {
				case 'BusinessEntityType':
					$property = 'customer_types';
				break;
				case 'DeliveryMethod':
					$property = 'delivery_options';
				break;
				case 'PaymentMethod':
					$property = 'payment_methods';
				break;
				case 'WarrantyScope':
					$property = 'warranty_promises';
				break;
			}

			if($$parameter_array_name != NULL && $property != NULL) {
				if($element == 'WarrantyScope') {
					$iter_arr = array();
					foreach($$parameter_array_name as $key => $value) {
						$warranty = array();
						$warranty['uri'] = SHOP_URI."#warrantypromise_${key}_${value}";
						$warranty['scope'] = $namespaces['gr'].$key;
						$warranty['duration'] = max($value, 0);
						$iter_arr[] = $warranty;
					}
					$product[$property] = $iter_arr;
				}
				else {
					$iter_arr = array();
					foreach($$parameter_array_name as $key => $value) {
						$iter_arr[] = $namespaces['gr'].$key;
					}
					$product[$property] = $iter_arr;
				}
			}
		}
		// business function
		if(($business_function = $this->_params->get('BusinessFunction')) != NULL) {
			$product['business_function'] = $namespaces['gr'].$business_function;
		}
		// eligible regions
		$regions_array = array();
		if(($eligible_regions = $this->_params->get('eligibleRegions')) != NULL) {
			$regions_array = explode(',', $eligible_regions);
			if(sizeof($regions_array)>0)
			foreach($regions_array as $key=>$value) {
				$regions_array[$key] = trim($value);
			}
		}
		$product['eligible_regions'] = $regions_array;

		// product discounted price
		if($product_discount_id > 0) {
		    $db_discount = new ps_DB;
			$db_discount->query("select amount, is_percent, start_date, end_date from #__{vm}_product_discount where discount_id='$product_discount_id'");
			if($db_discount->next_record()) {
				$product_special_amount = $db_discount->f('amount');
				$product_special_is_percent = $db_discount->f('is_percent');
				$product['product_special_start_date'] = $db_discount->f('start_date');
				$product['product_special_end_date'] = $db_discount->f('end_date')+86400; // valid for the whole last day... e.g. end_date = 26.01.2012 00:00:00, so add seconds of one additional day
				if($product['product_special_start_date'] > time() || ($product['product_special_end_date'] > 86400 && $product['product_special_end_date'] < time()))
				{
				    // price discount not valid at the moment
				}
				else {
    				$product['product_special_start_datestring'] = $this->w3cdate($product['product_special_start_date']);
    				if(empty($product['product_special_end_date']))
    					$product['product_special_end_date_default'] = $this->w3cdate(time()+$this->_params->get('special_validity')*86400);
    				$product['product_special_end_datestring'] = $this->w3cdate($product['product_special_end_date']);
    				// Calculate discounted special price
    				$product_special_price = $product_base_price;
    				if( !empty($product_special_amount)) {
    					switch( $product_special_is_percent ) {
    						case 0:
    							// If we subtract discounts BEFORE tax
    							if( PAYMENT_DISCOUNT_BEFORE == '1' ) {
    								// and if our prices are shown with tax
    								if( $auth["show_price_including_tax"] == 1) {
    									// then we add tax to the (untaxed) discount
    									$product_special_amount += ($product_tax*$product_special_amount);
    								} 
    								// but if our prices are shown without tax
    									// we just leave the (untaxed) discount amount as it is

    							}
    							// But, if we subtract discounts AFTER tax
    								// and if our prices are shown with tax
    									// we just leave the (untaxed) discount amount as it is
    								// but if  prices are shown without tax
    									// we just leave the (untaxed) discount amount as it is
    									// even though this is not really a good combination of settings

    							$product_special_price -= $product_special_amount;
    							break;
    						case 1:
    							$product_special_price *= (100 - $product_special_amount)/100;
    							break;
    					}
    				}
    				$product['product_special_price'] = number_format(max($product_special_price, 0), 2, ".", "");
			    }
			}
		}

		return $product;
	}
	
	function getAllCategories() {
		$db = &$this->db;
		$categories = array();
		
		$db->query("select t1.category_id, t1.category_name, t1.category_description, t2.category_parent_id"
			. " from #__{vm}_category t1"
			. " left join #__{vm}_category_xref t2 on t1.category_id=t2.category_child_id"
			. " left join #__{vm}_product_category_xref t3 on t1.category_id=t3.category_id"
			. " where t1.category_publish='Y' group by t1.category_id order by t1.category_id asc");
			
		while($db->next_record()) {
			$temp = array();
			$temp['id'] = intval($db->f('category_id'));
			$temp['uri'] = SHOP_URI."#category_".$temp['id'];
			$temp['name'] = $this->strip_tags($db->f('category_name'));
			$temp['description'] = $this->strip_tags($db->f('category_description'));
			$temp['parent_id'] = $category_parent_id = intval($db->f('category_parent_id'));
			$temp['parent'] = SHOP_URI."#category_".$category_parent_id;
			$categories[] = $temp;
		}
		return $categories;
	}
	
	// used for creating sitemap
	function getAllProductURIs() {
		$db = &$this->db;
		$sess = &$this->sess;
		$uris = array();
		$db->query("select product_id, mdate from #__{vm}_product where product_publish='Y'");
		$u = &JURI::getInstance(BASE_URI);
		while($db->next_record()) {
			$product_id = $db->f('product_id');
			$lastmod = $db->f('mdate');
			if(empty($lastmod))
				$lastmod = time();
			$changefreq = "daily";
			if($lastmod < time()-604800/*86400*7*/) {
				$changefreq = "weekly";
				if($lastmod < time()-2592000/*86400*30*/) {
					$changefreq = "monthly";
					if($lastmod < time()-31536000/*86400*365*/) {
						$changefreq = "yearly";
					}
				}
			}
			$uris[] = array(
				'uri' => preg_replace("/&amp;/i", "&", BASE_URI.preg_replace("/^\//i", "", str_replace(JURI::base(true), "", $sess->url('index.php?page=shop.product_details&product_id='.$product_id)))),
				//$u->getScheme().":".DS.DS.$u->getHost().($u->getPort()?":".$u->getPort():"").$sess->url('index.php?page=shop.product_details&product_id='.$product_id),
				'lastmod' => date("Y-m-d", $lastmod),
				'changefreq' => $changefreq,
				'priority' => "0.6"
			);
		}
		return $uris;
	}
		
	function getCompanyInfo() {
		$db = &$this->db;
		$company = array();
		$db->query("select vendor_name, vendor_url, contact_email,"
			. " vendor_zip, vendor_address_1, vendor_city, vendor_country,"
			. " vendor_phone, vendor_image_path, vendor_thumb_image, vendor_full_image"
			. " from #__{vm}_vendor"
			. " where 1 group by vendor_id order by vendor_id asc");
			
		if($db->next_record()) {
		    $company['maker'] = "urn:goodrelations_shop_extensions:goodrelations-for-joomla:v".$this->_params->get('version');
			$company['uri'] = SHOP_URI."#company_data";
			$company['addr_uri'] = SHOP_URI."#address_data";
			$company['company_name'] = $this->strip_tags($db->f('vendor_name'));
			$company['email'] = $db->f('contact_email');
			$company['language'] = $this->lang;
			$company['country'] = $db->f('vendor_country');
			$company['city'] = $db->f('vendor_city');
			$company['zip'] = $db->f('vendor_zip');
			$company['street'] = $db->f('vendor_address_1');
			$company['phone'] = $db->f('vendor_phone');
			$image = $db->f('vendor_thumb_image');
			if(!$image)
				$image = $db->f('vendor_full_image');
			$company['logo_uri'] = $image?IMAGEBASEPATH."vendor/".$image:"";
			$company['page'] = BASE_URI;
		}
		return $company;
	}
	
	function getAllStoreData() {
		$db = &$this->db;
		$stores = array();
		$db->query("select vendor_id,"
			. " vendor_store_name, vendor_store_desc, vendor_url,"
			. " vendor_zip, vendor_address_1, vendor_city, vendor_country,"
			. " vendor_phone, vendor_image_path, vendor_thumb_image, vendor_full_image"
			. " from #__{vm}_vendor"
			. " where 1 group by vendor_id");
			
		while($db->next_record()) {
			$vendor = array();
			$vendor['id'] = SHOP_URI."#vendor_".$db->f('vendor_id');
			$vendor['addr_id'] = SHOP_URI."#address_vendor_".$db->f('vendor_id');
			$vendor['name'] = $this->strip_tags($db->f('vendor_store_name'));
			$vendor['description'] = $this->strip_tags($db->f('vendor_store_desc'));
			$vendor['language'] = $this->lang;
			$vendor['country'] = $db->f('vendor_country');
			$vendor['city'] = $db->f('vendor_city');
			$vendor['zip'] = $db->f('vendor_zip');
			$vendor['street'] = $db->f('vendor_address_1');
			$vendor['phone'] = $db->f('vendor_phone');
			$image = $db->f('vendor_thumb_image');
			if(!$image)
				$image = $db->f('vendor_full_image');
			$vendor['logo_uri'] = $image?IMAGEBASEPATH."vendor/".$image:"";
			$vendor['page'] = BASE_URI;
			$stores[] = $vendor;
		}
		return array('company_uri' => SHOP_URI."#company_data", 'stores' => $stores);
	}
	
	function getAllManufacturerData() {
		$db = &$this->db;
		$manufacturer_array = array();
		$db->query("select manufacturer_id, mf_name, mf_url from #__{vm}_manufacturer"
			. " where 1 group by manufacturer_id");
		while($db->next_record()) {
			$manufacturer = array();
			$manufacturer['name'] = SHOP_URI."#manufacturer_".$db->f('manufacturer_id');
			$manufacturer['company_name'] = $db->f('mf_name');
			$manufacturer['uri'] = $db->f('mf_url');
			$manufacturer['language'] = $this->lang;
			$manufacturer_array[] = $manufacturer;
		}

		return $manufacturer_array;
	}
	
	function getReview($product_id) {
		$db = &$this->db;
		$sess = &$this->sess;
		$review_array = array();
		
		$review_array['rating'] = 0;
		$review_array['votes'] = 0;
		
		$db->query("select rating, allvotes from #__{vm}_product_votes"
			. " where product_id='$product_id'");
		if($db->next_record()) {
			$review_array['rating'] = max($db->f('rating'), 0);
			$review_array['votes'] = max($db->f('allvotes'), 0);
		}
		
		$u = &JURI::getInstance(BASE_URI);
		$p_uri_path = preg_replace("/&amp;/i", "&", $sess->url('index.php?page=shop.product_details&product_id='.$product_id));
		$review_array['product_uri'] = $u->getScheme().":".DS.DS.$u->getHost().($u->getPort()?":".$u->getPort():"").DS.preg_replace("/^\//i", "", $p_uri_path);
		$review_array['product_id'] = $product_id;
		
		return $review_array;
	}
}
?>